﻿using System.Reflection;
using NLite.Internal;

namespace NLite.Reflection
{
	delegate void Setter(object target, object value);

	/// <summary>
	/// 
	/// </summary>
	public static class SetterExtensions
	{
		/// <summary>
		/// 
		/// </summary>
		/// <param name="member"></param>
		/// <param name="target"></param>
		/// <param name="value"></param>
		public static void Set(this MemberInfo member, object target, object value)
		{

			if (target != null && target.GetType().IsValueType)
			{
				switch (member.MemberType)
				{
						case MemberTypes.Field: (member as FieldInfo).SetValue(target, value); break;
						case MemberTypes.Property: (member as PropertyInfo).SetValue(target, value, null); break;
						case MemberTypes.Method: (member as MethodInfo).Invoke(target, new object[] { value }); break;
				}
			}
			else
			{
				try
				{
					DynamicMethodFactoryProxy.Instance.CreateSetter(member)(target, value);
				}
				catch(TargetInvocationException ex)
				{
					throw ex.InnerException;
				}
			}
		}
	}
}
